package com.itcast.peft.service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.itcast.peft.config.MultipleModelConfig.ChatModelHolder;
import com.itcast.peft.util.AsyncWrapper;
import com.itcast.peft.util.ExceptionWrapper;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class HealthPDFGenerator {
    
    public static final String PDF_FOLDER = "./healthReport/";
    
    @Resource
    private ChatModelHolder healthGenModelHolder;
    
    private String promptTemplate;
    
    private String[] disease = new String[] {"阿尔茨海默病","帕金森病","骨质疏松症","高血压","糖尿病","冠心病","慢性阻塞性肺病","脑卒中","老年性白内障","前列腺增生","老年性黄斑变性","关节炎","慢性心力衰竭","老年性耳聋","抑郁症","慢性肾病","胃食管反流病","老年性痴呆","带状疱疹","肺纤维化","痛风","老年性皮肤瘙痒症","慢性支气管炎","动脉硬化","老年性便秘","失眠症","老年性肺炎","腰椎间盘突出","老年性尿失禁","老年性低血压"};
    
    @Autowired
    private AsyncWrapper asyncWrapper;
    
    @PostConstruct
    void init() throws IOException {
        try (var is = new ClassPathResource("prompt_healthreport_gen.txt").getInputStream()) {
            this.promptTemplate = IOUtils.toString(is, StandardCharsets.UTF_8);
        }
    }
    
    @Async
    public void generatePDF() {
        var futureList = Stream.iterate(0, i -> i + 1)
            .limit(14)
            .map(i -> (Runnable)this::generateSinglePDF)
            .map(r -> CompletableFuture.runAsync(r, this.asyncWrapper.getExecutor()))
            .toList();
        futureList.forEach(ExceptionWrapper.<CompletableFuture<Void>, Void>wrapToRTE(CompletableFuture::get)::apply);
    }
    
    private void generateSinglePDF() {
        var sexal = new String[] {"男", "女"};
        Random random = new Random();
        
        var rand = random.nextInt(100000, 999999);
        var age = random.nextInt(65, 95);
        var health = random.nextInt(2) == 0 ? "健康" : disease[random.nextInt(disease.length)];
        var sex = sexal[random.nextInt(sexal.length)];
        var profile = String.format("%s年龄%s岁情况为%s", sex, age, health);
        var html = healthGenModelHolder.getModel().call(String.format(promptTemplate, profile, rand));
        try {
            File f = new File(PDF_FOLDER + profile + rand + ".html");
            FileUtils.write(f, html, StandardCharsets.UTF_8);
            log.info("file generated:{}", f);
            buildPDF(rand, profile, f);
        } catch (Exception e) {
            log.error("error in html generation", e);
        }
    }

    private void buildPDF(int rand, String profile, File f) throws IOException, FileNotFoundException {
        try (OutputStream os = new FileOutputStream(PDF_FOLDER + profile + rand + ".pdf")) {
            PdfRendererBuilder builder = new PdfRendererBuilder();
            builder.useFastMode();
            builder.useFont(new File("./AlibabaPuHuiTi-3-55-Regular.ttf"), "Alibaba PuHuiTi 3.0");
            builder.withFile(f);
            builder.toStream(os);
            builder.run();
        }
    }
}
